package linkedlist;

/**
 * @author zhaoziqiang
 * @Description:
 * @date 2020/8/21 16:12
 */
public class LinkedList<E> {
    private Node dummyHead;
    private int size;

    private class Node {
        public E e;
        public Node next;

        public Node(E e, Node next) {
            this.e = e;
            this.next = next;
        }

        public Node(E e) {
            this(e, null);
        }

        public Node() {
            this(null, null);
        }

        @Override
        public String toString() {
            return "Node{" + "e=" + e + ", next=" + next + '}';
        }
    }

    public LinkedList() {
        this.dummyHead = new Node(null, null);
        this.size = 0;
    }

    public int getSize() {
        return size;
    }

    //index位置添加
    public void addIndex(E e, int index) {
        if (index < 0 || index > size)
            throw new IllegalArgumentException("Illegal index,add failed");
        //prev上一个元素
        Node prev = dummyHead;
        for (int i = 0; i < index; i++) {
            prev = prev.next;
        }
        prev.next = new Node(e, prev.next);
        size++;
    }

    //头部添加
    public void addHead(E e) {
        addIndex(e, 0);
    }

    //末尾添加
    public void addTail(E e) {
        addIndex(e, size);
    }

    //获取index位置元素
    public E getIndex(int index) {
        if (index < 0 || index >= size)
            throw new IllegalArgumentException("Illegal index,get failed");
        Node cur = dummyHead.next;
        for (int i = 0; i < index; i++) {
            cur = cur.next;
        }
        return cur.e;
    }
    //获取表头元素
    public E getHead() {
        return getIndex(0);
    }
    //获取末尾元素
    public E getTail() {
        return getIndex(size-1);
    }
    //修改index位置元素
    public void setIndex(int index, E e) {
        if (index < 0 || index >= size)
            throw new IllegalArgumentException("Illegal index,get failed");
        Node cur = dummyHead.next;
        for (int i = 0; i < index; i++)
            cur = cur.next;
        cur.e = e;
    }

    //删除index 位置元素
    public E remove(int index) {
        if (index < 0 || index >= size)
            throw new IllegalArgumentException("Illegal index,get failed");
        Node prev = dummyHead;
        for (int i = 0; i < index; i++) {
            prev=prev.next;
        }
        Node delNode=prev.next;
        prev.next=delNode.next;
        delNode.next=null;
        size--;
        return delNode.e;
    }
    public E removeHead() {return remove(0);}
    public E removeTail() {return remove(size-1);}
    //是否包含某元素
    public boolean contains(E e) {
        boolean result = false;
        Node cur = dummyHead.next;
        while (cur != null) {
            if (cur.e.equals(e)) {
                result = true;
                break;
            }
            cur = cur.next;
        }
        return result;
    }
    public void clearAll(){
        Node cur=dummyHead.next;
        Node p=null;
        while (cur!=null){
            p=cur.next;
            free(cur);
            cur=p;
        }
        dummyHead.next=null;

    }

    private void free(Node next) {
        next.next=null;
            }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
//        for (Node cur = dummyHead.next; cur!=null ; cur=cur.next) {
//            sb.append(cur.e+"->");
//        }
        Node cur = dummyHead.next;
        while (cur != null) {
            sb.append(cur.e+"->");
            cur = cur.next;
        }
        sb.append("null");
        return sb.toString();
    }

    public static void main(String[] args) {
        LinkedList<Integer> linkedList = new LinkedList<>();
        for (int i = 0; i <5 ; i++) {
            linkedList.addHead(i);
        }
//        System.out.println(linkedList);
//        linkedList.remove(2);
//        System.out.println(linkedList);
//        linkedList.removeHead();
//        System.out.println(linkedList);
//        linkedList.removeTail();
        System.out.println(linkedList);
        linkedList.clearAll();
        System.out.println(linkedList);

    }
}

